package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasFormRefEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.BIProductEnum;
import com.xbongbong.paas.enums.BIProductReformEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.ScreenTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasFormRefModel;
import com.xbongbong.paas.pojo.dto.FormEntityAddDTO;
import com.xbongbong.paas.pojo.dto.PaymentSheetExplainsSingleDTO;
import com.xbongbong.paas.script.pojo.dto.BiDataScriptDTO;
import com.xbongbong.paas.script.pojo.dto.BiExplainScriptDTO;
import com.xbongbong.paas.service.ProFormService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.domain.entity.ChartFavoriteEntity;
import com.xbongbong.pro.domain.entity.IndexSetEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.index.pojo.IndexSetDataPojo;
import com.xbongbong.pro.service.toolbox.statistic.help.FormHelp;
import com.xbongbong.pro.statistic.constant.ChartConstant;
import com.xbongbong.pro.statistic.model.ChartCategorySearchModel;
import com.xbongbong.pro.statistic.model.ChartCustomModel;
import com.xbongbong.pro.statistic.model.ChartFavoriteModel;
import com.xbongbong.pro.statistic.model.ChartModel;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.model.IndexSetModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.sys.help.SysEnvHelp;
import com.xbongbong.sys.model.CompanyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zhouwq
 * @date 2020/6/4 14:13
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX+"/script/bi")
public class BiDataScriptController {

    private static final Logger LOG = LoggerFactory.getLogger(BiDataScriptController.class);
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private IndexSetModel indexSetModel;
    @Resource
    private ChartFavoriteModel chartFavoriteModel;
    @Resource
    private ChartModel chartModel;
    @Resource
    private ChartCustomModel chartCustomModel;
    @Resource
    private ChartCategorySearchModel chartCategorySearchModel;
    @Resource
    private FormHelp formHelp;
    @Resource
    private PaasFormRefModel paasFormRefModel;
    @Resource
    private SysEnvHelp sysEnvHelp;
    @Resource
    private ProFormService proFormService;

    @RequestMapping(value = "/init/biProductEnumInit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String biProductEnumInit(@RequestBody @Valid BiDataScriptDTO biDataScriptDTO, BindingResult br) {
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //验证码
                if(!proBaseConfig.getXbbCode().equals(biDataScriptDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                List<String> corpidList = companyModel.getCorpidList();
                Map<String, Object> param = new HashMap<>(1 << 4);
                param.put("columns", "id, app_id, business_type, corpid");
                param.put("del", DelEnum.NORMAL.getDel());
                param.put("businessType", XbbRefTypeEnum.PRODUCT.getCode());
                List<PaasFormEntity> paasFormEntities = paasFormModel.findEntity(param);
                Map<String, Long> corpIdToAppIdMapping = new HashMap<>(paasFormEntities.size());
                paasFormEntities.forEach(e -> corpIdToAppIdMapping.put(e.getCorpid(), e.getAppId()));
                int corpCounts = corpidList.size();
                BIProductEnum[] biProductEnums = BIProductEnum.values();
                //TODO 少了两个出库单和入库单  上线后补充
                List<BIProductEnum> oldList = Arrays.asList(BIProductEnum.CONTRACT_PRODUCT, BIProductEnum.RETURNED_PURCHASE_PRODUCT, BIProductEnum.SALES_OPPORTUNITY_PRODUCT, BIProductEnum.SUPPLIER_PRODUCT, BIProductEnum.PURCHASE_PRODUCT, BIProductEnum.PRODUCTION_ORDER_PRODUCT);
//                List<BIProductEnum> oldList = Arrays.asList(BIProductEnum.CONTRACT_PRODUCT, BIProductEnum.RETURNED_PURCHASE_PRODUCT, BIProductEnum.SALES_OPPORTUNITY_PRODUCT, BIProductEnum.SUPPLIER_PRODUCT, BIProductEnum.PURCHASE_PRODUCT, BIProductEnum.PRODUCTION_ORDER_PRODUCT, BIProductEnum.INSTOCK_PRODUCT, BIProductEnum.OUTSTOCK_PRODUCT);
                long now = DateUtil.getNow();
                for (int i = 0; i < corpCounts; i++) {
                    LOG.warn("处理进度：" + (i + 1) + "/" + corpCounts);
                    String corpid = corpidList.get(i);
                    List<PaasFormEntity> formList = new ArrayList<>();
                    Long appId = corpIdToAppIdMapping.get(corpid);
                    if (appId == null) {
                        continue;
                    }
                    for (BIProductEnum value : biProductEnums) {
                        if (oldList.contains(value)) {
                            continue;
                        }
                        PaasFormEntity paasFormEntity = new PaasFormEntity();
                        FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
                        BeanUtil.copyProperties(formEntityAddDTO, paasFormEntity);
                        paasFormEntity.setBusinessType(value.getCode());
                        paasFormEntity.setAppId(appId);
                        paasFormEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
                        paasFormEntity.setName(value.getName());
                        paasFormEntity.setAddTime(now);
                        paasFormEntity.setUpdateTime(now);
                        paasFormEntity.setCorpid(corpid);
                        paasFormEntity.setMenuId(0L);
//                        formEntityAddDTO.setCreatorId(creatorId);
                        paasFormEntity.setCoOpPerms(JSONObject.toJSONString(formEntityAddDTO.getCoOpPerms()));
                        paasFormEntity.setSummary(JSONObject.toJSONString(formEntityAddDTO.getSummaryEntity()));
                        paasFormEntity.setLabels(JSONObject.toJSONString(formEntityAddDTO.getLabels()));
                        paasFormEntity.setAssociationList(JSONObject.toJSONString(formEntityAddDTO.getAssociationList()));
                        paasFormEntity.setBusinessRules(JSONObject.toJSONString(formEntityAddDTO.getBusinessRules()));
                        paasFormEntity.setSurcharge(JSONObject.toJSONString(formEntityAddDTO.getSurcharge()));
                        paasFormEntity.setCustomTitle(JSONObject.toJSONString(formEntityAddDTO.getCustomTitle()));
                        paasFormEntity.setCreatorId("1");
                        paasFormEntity.setSort(0);
                        formList.add(paasFormEntity);
                    }
                    paasFormModel.insertBatch(formList);
                }
                response = new XbbResponse<>("");
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/init/biFixScreenType", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String biFixScreenType(@RequestBody @Valid BiDataScriptDTO biDataScriptDTO, BindingResult br) {
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //验证码
                if(!proBaseConfig.getXbbCode().equals(biDataScriptDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                List<Integer> businessTypeList = Arrays.asList(XbbRefTypeEnum.BOM_BILL.getCode(), XbbRefTypeEnum.CONTRACT.getCode(),
                        XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.PAYMENT.getCode(), XbbRefTypeEnum.PAY_PLAN.getCode(),
                        XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), XbbRefTypeEnum.PURCHASE.getCode(), XbbRefTypeEnum.QUOTATION.getCode(),
                        XbbRefTypeEnum.REFUND.getCode(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.SUPPLIER_CONTACT.getCode(),
                        XbbRefTypeEnum.SUPPLIER.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode(), XbbRefTypeEnum.CONTACT.getCode());
                List<String> corpidList = biDataScriptDTO.getCorpidList() != null && biDataScriptDTO.getCorpidList().size() > 0 ? biDataScriptDTO.getCorpidList() : companyModel.getCorpidList();
                int corpCounts = corpidList.size();
                Map<String, Object> params = new HashMap<>(5);
                params.put("businessTypeList", businessTypeList);
                for (int i = 0; i < corpCounts; i++) {
                    LOG.warn("处理进度：" + (i + 1) + "/" + corpCounts);
                    String corpid = corpidList.get(i);
                    params.put("corpid", corpid);
                    params.put("del", DelEnum.NORMAL.getDel());
                    params.put("enable", BasicConstant.ONE);
                    params.put("saasMark", BasicConstant.ONE);
                    List<PaasFormExplainEntity> paasFormExplainEntities = paasFormExplainModel.findEntitys(params);
                    paasFormExplainEntities.forEach(e -> {
                        List<FieldAttrEntity> oldFieldAttrEntities = JSON.parseArray(e.getExplains(), FieldAttrEntity.class);
                        oldFieldAttrEntities.forEach(field -> {
                            if (Objects.equals(field.getAttr(), "ownerId")) {
                                if (!Objects.equals(field.getBusinessType(), XbbRefTypeEnum.CONTACT.getCode())) {
                                    field.setScreenType(ScreenTypeEnum.SCREEN_GROUP.getType());
                                }
                            } else if (Objects.equals(field.getSaasAttr(), "address")) {
                                field.setScreenType(ScreenTypeEnum.SCREEN_GROUP.getType());
                            } else if (Objects.equals(XbbRefTypeEnum.PURCHASE.getCode(), e.getBusinessType()) && Objects.equals(PurchaseEnum.SUPPLIER_ID.getAttr(), field.getAttr())) {
                                field.setScreenType(ScreenTypeEnum.SCREEN_GROUP.getType());
                            }
                        });
                        String fieldAttrStr = JSON.toJSONString(oldFieldAttrEntities);
                        e.setExplains(fieldAttrStr);
                    });
                    if (paasFormExplainEntities.size() > 0) {
                        paasFormExplainModel.updateBatchExplains(paasFormExplainEntities);
                    }
                }
                response = new XbbResponse<>("");
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/init/biFixWorkOrderScreenType", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String biFixWorkOrderScreenType(@RequestBody @Valid BiDataScriptDTO biDataScriptDTO, BindingResult br) {
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //验证码
                if(!proBaseConfig.getXbbCode().equals(biDataScriptDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                List<Integer> businessTypeList = Collections.singletonList(XbbRefTypeEnum.WORK_ORDER.getCode());
                List<String> corpidList = biDataScriptDTO.getCorpidList() != null && biDataScriptDTO.getCorpidList().size() > 0 ? biDataScriptDTO.getCorpidList() : companyModel.getCorpidList();
                int corpCounts = corpidList.size();
                Map<String, Object> params = new HashMap<>(5);
                params.put("businessTypeList", businessTypeList);
                for (int i = 0; i < corpCounts; i++) {
                    LOG.warn("处理进度：" + (i + 1) + "/" + corpCounts);
                    String corpid = corpidList.get(i);
                    params.put("corpid", corpid);
                    params.put("del", DelEnum.NORMAL.getDel());
                    List<WorkOrderExplainEntity> workOrderExplainEntities = workOrderExplainModel.findEntitys(params);
                    workOrderExplainEntities.forEach(e -> {
                        List<FieldAttrEntity> oldFieldAttrEntities = JSON.parseArray(e.getExplains(), FieldAttrEntity.class);
                        oldFieldAttrEntities.forEach(field -> {
                            if (Objects.equals(field.getAttr(), "ownerId")) {
                                field.setScreenType(ScreenTypeEnum.SCREEN_SEARCH.getType());
                            }
                        });
                        String fieldAttrStr = JSON.toJSONString(oldFieldAttrEntities);
                        e.setExplains(fieldAttrStr);
                    });
                    if (workOrderExplainEntities.size() > 0) {
                        workOrderExplainModel.updateBatchExplain(workOrderExplainEntities, corpid);
                    }
                }
                response = new XbbResponse<>("");
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 刷ScreenType
     *  只能单个业务刷  因为attr不一致
     * @param biExplainScriptDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/init/biFixScreenTypeByBuss", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String biFixScreenTypeByBuss(@RequestBody @Valid BiExplainScriptDTO biExplainScriptDTO, BindingResult br) {
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //验证码
                if(!proBaseConfig.getXbbCode().equals(biExplainScriptDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                if(CollectionsUtil.isNotEmpty(biExplainScriptDTO.getCorpidList())){
                    params.put("corpidIn", biExplainScriptDTO.getCorpidList());
                }
                params.put("pageSize", 100);
                //按id排序
                params.put("orderByStr", "id");
                // 只能单个业务刷
                Integer businessType = biExplainScriptDTO.getBusinessType();
                params.put("businessType", businessType);
                params.put("del", DelEnum.NORMAL.getDel());
                boolean flag = true;
                List<String> attrList = biExplainScriptDTO.getAttrList();
                Integer count = 0;
                LOG.info("======开始处理========="+count);
                while (flag){
                    List<PaasFormExplainEntity> paasFormExplainEntities = paasFormExplainModel.findEntitys(params);
                    if (paasFormExplainEntities == null || paasFormExplainEntities.isEmpty()) {
                        flag = false;
                    } else {
                        params.put("idGte",paasFormExplainEntities.get(paasFormExplainEntities.size() - 1).getId());
                        paasFormExplainEntities.forEach(e -> {
                            List<FieldAttrEntity> oldFieldAttrEntities = JSON.parseArray(e.getExplains(), FieldAttrEntity.class);
                            oldFieldAttrEntities.forEach(field -> {
                                if (attrList.contains(field.getAttr())) {
                                    if(Objects.equals(businessType,XbbRefTypeEnum.PRODUCT.getCode())){
                                        field.setScreenType(ProductEnum.getByAttr(field.getAttr()).getScreenType());
                                    }else if(Objects.equals(businessType,XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode())){
                                        field.setScreenType(CustomerCommunicateEnum.getByAttr(field.getAttr()).getScreenType());
                                    } else if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode())) {
                                        field.setScreenType(PurchaseEnum.getByAttr(field.getAttr()).getScreenType());
                                    }
                                }
                            });
                            String fieldAttrStr = JSON.toJSONString(oldFieldAttrEntities);
                            e.setExplains(fieldAttrStr);
                        });
                        paasFormExplainModel.updateBatchExplains(paasFormExplainEntities);
                        count = count+paasFormExplainEntities.size();
                        LOG.info("======处理进度========="+count);
                    }
                }
                LOG.info("======处理结束========="+count);
                response = new XbbResponse<>("");
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/init/biFormatIndexSet", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String biFormatIndexSet(@RequestBody @Valid BiDataScriptDTO biDataScriptDTO, BindingResult br) {
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //验证码
                if(!proBaseConfig.getXbbCode().equals(biDataScriptDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                List<String> corpidList = biDataScriptDTO.getCorpidList() != null && biDataScriptDTO.getCorpidList().size() > 0 ? biDataScriptDTO.getCorpidList() : companyModel.getCorpidList();
                int corpCounts = corpidList.size();
                for (int i = 0; i < corpCounts; i++) {
                    LOG.warn("处理进度：" + (i + 1) + "/" + corpCounts);
                    String corpid = corpidList.get(i);
                    List<IndexSetEntity> indexSetEntities = indexSetModel.findByBiScript(corpid);
                    Set<Long> chartIdList = new HashSet<>();
                    indexSetEntities.forEach(e -> {
                        List<IndexSetDataPojo> indexSetDataList = e.getContentData().toJavaList(IndexSetDataPojo.class);
                        indexSetDataList.forEach(indexSetDataPojo -> {
                            if (indexSetDataPojo.getSecondCategoryId() != null && indexSetDataPojo.getChartCategoryType() == ChartConstant.CHART_CATEGORY_TYPE_CHART) {
                                chartIdList.add(indexSetDataPojo.getChartCategoryId());
                            }
                        });
                    });
                    Map<String, Object> param = new HashMap<>(1);
                    param.put("idIn", chartIdList);
                    param.put("del", DelEnum.NORMAL.getDel());
                    List<ChartEntity> charts = chartModel.findEntitys(param);
                    charts.addAll(chartCustomModel.findEntitys(param));
                    Map<Long, Integer> chartToStatisticsType = new HashMap<>(charts.size());
                    charts.forEach(e -> chartToStatisticsType.put(e.getId(), e.getStatisticsType()));
                    indexSetEntities.forEach(e -> {
                        List<IndexSetDataPojo> indexSetDataList = e.getContentData().toJavaList(IndexSetDataPojo.class);
                        indexSetDataList.forEach(indexSetDataPojo -> {
                            if (indexSetDataPojo.getSecondCategoryId() != null && indexSetDataPojo.getChartCategoryType() == ChartConstant.CHART_CATEGORY_TYPE_CHART) {
                                indexSetDataPojo.setStatisticsType(chartToStatisticsType.get(indexSetDataPojo.getChartCategoryId()));
                            }
                        });
                        e.setContentData(JSON.parseArray(JSON.toJSONString(indexSetDataList)));
                    });
                    if (indexSetEntities.size() > 0) {
                        indexSetModel.updateBatch(indexSetEntities, corpid);
                    }
                }
                response = new XbbResponse<>("");
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/init/biFormatChartFavorite", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String biFormatChartFavorite(@RequestBody @Valid BiDataScriptDTO biDataScriptDTO, BindingResult br) {
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //验证码
                if(!proBaseConfig.getXbbCode().equals(biDataScriptDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                Map<String, Object> param = new HashMap<>(1 << 4);
                param.put("del", DelEnum.NORMAL.getDel());
                List<ChartFavoriteEntity> favoriteEntities = chartFavoriteModel.findEntitys(param);
                Set<Long> chartIdIn = new HashSet<>();
                Map<Long, ChartFavoriteEntity> chartIdToChartFavorite = new HashMap<>(favoriteEntities.size());
                favoriteEntities.forEach(e -> {
                    chartIdIn.add(e.getChartId());
                    chartIdToChartFavorite.put(e.getChartId(), e);
                });
                param.put("idIn", chartIdIn);
                List<ChartEntity> chartEntities = chartModel.findEntitys(param);
                chartEntities.addAll(chartCustomModel.findEntitys(param));
                chartEntities.forEach(e -> {
                    ChartFavoriteEntity chartFavoriteEntity = chartIdToChartFavorite.get(e.getId());
                    chartFavoriteEntity.setStatisticsType(e.getStatisticsType());
                });
                chartFavoriteModel.updateBatch(favoriteEntities);
                LOG.info("======处理结束=========");
                response = new XbbResponse<>("");
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/init/biFixPicScreenType", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String biFixPicScreenType(@RequestBody @Valid BiDataScriptDTO biDataScriptDTO, BindingResult br) {
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //验证码
                if(!proBaseConfig.getXbbCode().equals(biDataScriptDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                List<Integer> businessTypeList = Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(),
                        XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(), XbbRefTypeEnum.PRODUCT.getCode(),
                        XbbRefTypeEnum.SUPPLIER_COMMUNICATE.getCode(), XbbRefTypeEnum.SUPPLIER.getCode());
                List<String> corpidList = biDataScriptDTO.getCorpidList() != null && biDataScriptDTO.getCorpidList().size() > 0 ? biDataScriptDTO.getCorpidList() : companyModel.getCorpidList();
                int corpCounts = corpidList.size();
                Map<String, Object> params = new HashMap<>(5);
                params.put("businessTypeList", businessTypeList);
                for (int i = 0; i < corpCounts; i++) {
                    LOG.warn("处理进度：" + (i + 1) + "/" + corpCounts);
                    String corpid = corpidList.get(i);
                    params.put("corpid", corpid);
                    params.put("del", DelEnum.NORMAL.getDel());
                    params.put("enable", BasicConstant.ONE);
                    params.put("saasMark", BasicConstant.ONE);
                    List<PaasFormExplainEntity> paasFormExplainEntities = paasFormExplainModel.findEntitys(params);
                    paasFormExplainEntities.forEach(e -> {
                        List<FieldAttrEntity> oldFieldAttrEntities = JSON.parseArray(e.getExplains(), FieldAttrEntity.class);
                        oldFieldAttrEntities.forEach(field -> {
                            if (Objects.equals(field.getAttr(), "file_1")) {
                                field.setScreenType(ScreenTypeEnum.SCREEN_SHOW.getType());
                            }
                        });
                        String fieldAttrStr = JSON.toJSONString(oldFieldAttrEntities);
                        e.setExplains(fieldAttrStr);
                    });
                    if (paasFormExplainEntities.size() > 0) {
                        paasFormExplainModel.updateBatchExplains(paasFormExplainEntities);
                    }
                }
                response = new XbbResponse<>("");
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/init/biUpdateNewData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String biUpdateNewData(@RequestBody @Valid BiDataScriptDTO biDataScriptDTO, BindingResult br) {
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //验证码
                if(!proBaseConfig.getXbbCode().equals(biDataScriptDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                Map<Long, Long> idMapping = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                List<Long> oldIdList = new ArrayList<>();
                List<ChartEntity> chartEntities = chartModel.getEntitysByNewData();
                for (ChartEntity chartEntity : chartEntities) {
                    Long oldId = chartEntity.getId();
                    oldIdList.add(oldId);
                    chartEntity.setId(null);
                    chartCustomModel.insert(chartEntity);
                    idMapping.put(oldId, chartEntity.getId());
                }
                LOG.info("处理进度：更新图表ID > 5844142部分数据完成");
                boolean isGrayEnvironmentEnable = sysEnvHelp.isGrayEnvironmentEnable();
                List<String> corpidList = biDataScriptDTO.getCorpidList() != null && biDataScriptDTO.getCorpidList().size() > 0 ? biDataScriptDTO.getCorpidList() : companyModel.getCorpidList();
                int corpCounts = corpidList.size();
                for (int i = 0; i < corpCounts; i++) {
                    LOG.info("处理进度：" + (i + 1) + "/" + corpCounts);
                    String corpid = corpidList.get(i);

                    if (sysEnvHelp.isGrayEnvironment()) {
                        if (!isGrayEnvironmentEnable) {
                            continue;
                        }
                        if (!sysEnvHelp.checkIsCrayCompany(corpid)) {
                            continue;
                        }
                    } else {
                        if (isGrayEnvironmentEnable) {
                            if (sysEnvHelp.checkIsCrayCompany(corpid)) {
                                continue;
                            }
                        }
                    }

                    List<IndexSetEntity> indexSetEntities = indexSetModel.findByBiScript(corpid);
                    indexSetEntities.forEach(e -> {
                        List<IndexSetDataPojo> indexSetDataList = e.getContentData().toJavaList(IndexSetDataPojo.class);
                        indexSetDataList.forEach(indexSetDataPojo -> {
                            if (indexSetDataPojo.getSecondCategoryId() != null && indexSetDataPojo.getChartCategoryType() == ChartConstant.CHART_CATEGORY_TYPE_CHART) {
                                if (oldIdList.contains(indexSetDataPojo.getChartCategoryId())) {
                                    Long newId = idMapping.get(indexSetDataPojo.getChartCategoryId());
                                    if (newId != null) {
                                        indexSetDataPojo.setChartCategoryId(newId);
                                    }
                                }
                            }
                        });
                        e.setContentData(JSON.parseArray(JSON.toJSONString(indexSetDataList)));
                    });
                    if (indexSetEntities.size() > 0) {
                        indexSetModel.updateBatch(indexSetEntities, corpid);
                    }
                }
                response = new XbbResponse<>("");
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/biMemoAttrFix", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String biMemoAttrFix(@RequestBody @Valid BiDataScriptDTO biDataScriptDTO, BindingResult br) {
        XbbResponse<String> response;
        List<Integer> businessTypeList = Arrays.asList(1301, 2601, 802, 903, 1408, 702, 1201, 1001, 1002,501,
                502, 1407, 701, 901, 2801, 1401, 1504, 601, 801, 1405, 1701, 1505, 401, 1501, 1507, 1101,
                1404, 202, 1601, 1801, 1508);
        //工单2301 单独处理
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //验证码
                if(!proBaseConfig.getXbbCode().equals(biDataScriptDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                if(CollectionsUtil.isNotEmpty(biDataScriptDTO.getCorpidList())){
                    params.put("corpidIn", biDataScriptDTO.getCorpidList());
                }
                params.put("pageSize", 100);
                //按id排序
                params.put("orderByStr", "id");
                params.put("businessTypeIn", businessTypeList);
                params.put("del", DelEnum.NORMAL.getDel());
                boolean flag = true;
                Integer count = 0;
                LOG.info("======开始处理========="+count);
                while (flag){
                    List<PaasFormExplainEntity> paasFormExplainEntities = paasFormExplainModel.findEntitys(params);
                    if (paasFormExplainEntities == null || paasFormExplainEntities.isEmpty()) {
                        flag = false;
                    } else {
                        params.put("idGte",paasFormExplainEntities.get(paasFormExplainEntities.size() - 1).getId());
                        paasFormExplainEntities.forEach(e -> {
                            List<FieldAttrEntity> oldFieldAttrEntities = JSON.parseArray(e.getExplains(), FieldAttrEntity.class);
                            oldFieldAttrEntities.forEach(field -> {
                                if (Objects.equals(field.getSaasAttr(), "memo")) {
                                    field.setScreenType(ScreenTypeEnum.SCREEN_SHOW.getType());
                                }
                            });
                            String fieldAttrStr = JSON.toJSONString(oldFieldAttrEntities);
                            e.setExplains(fieldAttrStr);
                        });
                        paasFormExplainModel.updateBatchExplains(paasFormExplainEntities);
                        count = count+paasFormExplainEntities.size();
                        LOG.info("======处理进度========="+count);
                    }
                }
                LOG.info("======处理结束========="+count);
                Map<String, Object> workOrderParams = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                if(CollectionsUtil.isNotEmpty(biDataScriptDTO.getCorpidList())){
                    workOrderParams.put("corpidIn", biDataScriptDTO.getCorpidList());
                }
                workOrderParams.put("pageSize", 100);
                //按id排序
                workOrderParams.put("orderByStr", "id");
                workOrderParams.put("del", DelEnum.NORMAL.getDel());
                boolean workOrderflag = true;
                Integer workOrderCount = 0;
                LOG.info("======工单部分开始处理========="+workOrderCount);
                while (workOrderflag){
                    List<WorkOrderExplainEntity> workOrderExplainEntities = workOrderExplainModel.findEntitys(workOrderParams);
                    if (workOrderExplainEntities == null || workOrderExplainEntities.isEmpty()) {
                        workOrderflag = false;
                    } else {
                        workOrderParams.put("idGte",workOrderExplainEntities.get(workOrderExplainEntities.size() - 1).getId());
                        workOrderExplainEntities.forEach(e -> {
                            List<FieldAttrEntity> oldFieldAttrEntities = JSON.parseArray(e.getExplains(), FieldAttrEntity.class);
                            oldFieldAttrEntities.forEach(field -> {
                                if (Objects.equals(field.getSaasAttr(), "memo")) {
                                    field.setScreenType(ScreenTypeEnum.SCREEN_SHOW.getType());
                                }
                            });
                            String fieldAttrStr = JSON.toJSONString(oldFieldAttrEntities);
                            e.setExplains(fieldAttrStr);
                        });
                        workOrderExplainModel.updateBatchExplainNoCorpid(workOrderExplainEntities);
                        workOrderCount = workOrderCount+workOrderExplainEntities.size();
                        LOG.info("======工单部分处理进度========="+workOrderCount);
                    }
                }
                response = new XbbResponse<>("");
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/biPositionFix", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String biPositionFix(@RequestBody @Valid BiDataScriptDTO biDataScriptDTO, BindingResult br) {
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //验证码
                if(!proBaseConfig.getXbbCode().equals(biDataScriptDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                Map<String, Object> param = new HashMap<>(1 << 4);
                param.put("del", DelEnum.NORMAL.getDel());
                param.put("columns", "id,explains,category");
                List<ChartEntity> list = chartCustomModel.findEntitys(param);
                List<ChartEntity> updateList = new ArrayList<>();
                list.forEach(chartEntity -> {
                    ChartEntity updateEntity = new ChartEntity();
                    updateEntity.setId(chartEntity.getId());
                    JSONObject explains = chartEntity.getExplains();
                    if (explains == null) {
                        return;
                    }
                    JSONObject position = explains.getJSONObject("position");
                    JSONArray category = chartEntity.getCategory();
                    if (position == null || position.containsKey(category.getString(0))) {
                        return;
                    }
                    JSONObject newPosition = new JSONObject();
                    newPosition.put(category.getString(0), position);
                    explains.put("position", newPosition);
                    updateEntity.setExplains(explains);
                    updateList.add(updateEntity);
                });
                int size = updateList.size();
                for (int i = 0; i < size; i += 1000) {
                    int toIndex = i + 1000;
                    if (toIndex > size) {
                        toIndex = updateList.size();
                    }
                    List<ChartEntity> newList = updateList.subList(i, toIndex);
                    if(CollectionsUtil.isNotEmpty(newList)){
                        chartCustomModel.updateBatchNoCorpId(newList);
                    }
                }
                response = new XbbResponse<>("");
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }


    /**
     * 关联产品需求：如果主业务表单下面有产品子表单的话，需要对应生成对应的产品子表单
     *
     * @param paymentSheetExplainsSingleDTO
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/oldFormDataHandle", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String oldFormDataHandle(@RequestBody @Valid PaymentSheetExplainsSingleDTO paymentSheetExplainsSingleDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetExplainsSingleDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            LocaleContextHolder.setLocale(Locale.CHINA);
            LOG.info("-----------生成与主业务（主业务要有产品子表单）对应的产品子表单-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Integer start = 0;
            //每次查询300条
            Integer pageNum = 300;
            Long idGte = 0L;
            param.put("start", start);
            param.put("pageNum", pageNum);
            param.put("orderByStr", "id asc");
            param.put("del", 0);
            Set<Integer> allBusinessTypes =  BIProductReformEnum.getAllBusinessTypes();
            param.put("businessTypeList", allBusinessTypes);
            param.put("corpidIn", paymentSheetExplainsSingleDTO.getCorpidIn());
            while (true) {
                param.put("idGte", idGte);
                LOG.warn("处理进度：已处理到 tb_paas_form.id = " + idGte);
                //回款单表单
                List<PaasFormEntity> paasFormEntityExts = paasFormModel.findEntity(param);
                if (CollectionsUtil.isEmpty(paasFormEntityExts)) {
                    break;
                }
                idGte = paasFormEntityExts.get(paasFormEntityExts.size() - 1).getId();
                paasFormModel.insertSubProductFormList(paasFormEntityExts, allBusinessTypes);
            }
            LOG.warn("-----------time consume oldFormDataHandle:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------/script/bi/relatedProduct/oldFormDataHandle over");
        } catch (Exception e) {
            LOG.error("/script/bi/relatedProduct/oldFormDataHandle error", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     *修复paas关系表脏数据脚本
     *
     * @param paymentSheetExplainsSingleDTO
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/fixPaasFormRefData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixPaasFormRefData(@RequestBody @Valid PaymentSheetExplainsSingleDTO paymentSheetExplainsSingleDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(paymentSheetExplainsSingleDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            LocaleContextHolder.setLocale(Locale.CHINA);
            LOG.info("-----------修复paas关系表脏数据脚本-----------");
            long timeStart = DateTimeUtil.getInt();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("del", 0);
            Set<Integer> allBusinessTypes =  BIProductReformEnum.getAllBusinessTypes();
            param.put("businessTypeList", allBusinessTypes);
            for (String corpid : paymentSheetExplainsSingleDTO.getCorpidIn()) {
                param.put("corpid", corpid);
                LOG.info("-----------公司id:{}" , corpid);
                //需要先把一些脏数据删除掉
                Map<String, Object> paasRefParam = new HashMap<>();
                paasRefParam.put("corpid", corpid);
                paasRefParam.put("del", BasicConstant.ZERO);
                List<PaasFormRefEntity> paasFormRefEntities = paasFormRefModel.findEntitys(paasRefParam);
                if (CollectionsUtil.isEmpty(paasFormRefEntities)) {
                    continue;
                }
                Set<Long> mainFormIds = paasFormRefEntities.stream().map(PaasFormRefEntity::getMainFormId).collect(Collectors.toSet());
                Map<String, Object> mainFormMap = new HashMap<>();
                mainFormMap.put("corpid", corpid);
                mainFormMap.put("del", BasicConstant.ONE);
                mainFormMap.put("idIn", mainFormIds);
                List<PaasFormEntityExt> mainFormList = paasFormModel.findEntitys(mainFormMap);
                if (CollectionsUtil.isEmpty(mainFormList)) {
                    continue;
                }
                List<Long> shouldCompareFormIdList = new ArrayList<>();
                if (CollectionsUtil.isNotEmpty(mainFormList)) {
                    shouldCompareFormIdList = mainFormList.stream().map(PaasFormEntityExt::getId).collect(Collectors.toList());
                }
                List<Long> shouldDeletePaasFormList = new ArrayList<>();
                List<Long> shouldDeletePaasFormRefList = new ArrayList<>();
                if (CollectionsUtil.isNotEmpty(paasFormRefEntities)) {
                    for (PaasFormRefEntity paasFormRefEntity : paasFormRefEntities) {
                        if (shouldCompareFormIdList.contains(paasFormRefEntity.getMainFormId())) {
                            shouldDeletePaasFormList.add(paasFormRefEntity.getFormId());
                            shouldDeletePaasFormRefList.add(paasFormRefEntity.getId());
                        }
                    }
                }
                if (CollectionsUtil.isNotEmpty(shouldDeletePaasFormRefList)) {
                    paasFormRefModel.deleteBatch(shouldDeletePaasFormRefList, corpid);
                }
                if (CollectionsUtil.isNotEmpty(shouldDeletePaasFormList)) {
                    paasFormModel.deleteBatch(shouldDeletePaasFormList, corpid);
                }

                //哪些需要重新生成的呢，就先根据主业务去主表查询一下，然后比对一下子表是不是有数据了，如果有了就不重新生成
                List<PaasFormEntity> shouldInsertMainFormList = new ArrayList<>();
                List<PaasFormEntity> paasFormEntityExts = paasFormModel.findEntity(param);
                for (PaasFormEntity paasFormEntity : paasFormEntityExts) {
                    if (!shouldCompareFormIdList.contains(paasFormEntity.getId())) {
                        shouldInsertMainFormList.add(paasFormEntity);
                    }
                }
                if (CollectionsUtil.isEmpty(shouldInsertMainFormList)) {
                    break;
                }
                paasFormModel.insertSubProductFormList(shouldInsertMainFormList, allBusinessTypes);
            }
            LOG.warn("-----------time consume fixPaasFormRefData:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------/script/bi/relatedProduct/fixPaasFormRefData over");
        } catch (Exception e) {
            LOG.error("/script/bi/relatedProduct/fixPaasFormRefData error", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

}
